package it.uniroma2.drp;

import java.util.Vector;

import it.uniroma2.dtk.dt.GenericDT;
import it.uniroma2.util.math.ArrayMath;
import it.uniroma2.util.tree.Tree;

public class InputVectorGenerator {

	private int type;
	
	private GenericDT ts = null;
	
	/**
	 * 
	 * @param type
	 *        1   : unigrams of pos-tags
	 *        2   : unigrams+bigrams of pos-tags
	 *        3   : unigrams+bigrams+trigrams of pos-tags
	 * @param dt_generator
	 */
	public InputVectorGenerator(int type, GenericDT dt_generator) {
		this.type = type; ts = dt_generator;
	}
	
	/**
	 * produces the distributed input vetor for a drp with respect to the input type
	 * @param t
	 * @return 
	 * @throws Exception 
	 */
	public double [] generate(Tree t) throws Exception {
		double [] iv = ts.getVectorProvider().generateZeroVector(); 
		Vector<Tree> preterminals = preterminals(t);

//		System.out.println();
//		for (Tree tt:preterminals) {System.out.print(" " + tt.getRootLabel());}
//		System.out.println();

		for (int i = preterminals.size(); i > 0; i--) {
//			if (iv == null) {
//				iv = ts.getLabelVector(preterminals.get(i-1));
//			}
//			else {
			// ADDs THE UNIGRAM
//			System.out.print(preterminals.get(i-1).getRootLabel());
			double[] temp = ts.getLabelVector(preterminals.get(i-1));
			iv = ArrayMath.sum(iv,temp);
			// ADDs THE (J+1)-GRAMS
			for (int j = 1; j < type; j++) {
				if (i-1-j >= 0) {
//					System.out.print(" " + preterminals.get(i-1-j).getRootLabel());
					temp = ts.op(ts.getLabelVector(preterminals.get(i-1-j)),temp);
					iv = ArrayMath.sum(iv,temp);
				}
			}
//			System.out.println();
//			}
		}
		return iv;
		
	}
	
	/**
	 * generates the list of pre-terminal nodes of t
	 * @param t
	 * @return the list of pre-terminal nodes of t
	 */
	public Vector<Tree>  preterminals(Tree t) {
		Vector<Tree> pts = new Vector<Tree>();
		if (t.getChildren().size() == 1 && t.getChildren().get(0).isTerminal()) pts.add(t);
		else for (Tree tsub:t.getChildren()) pts.addAll(preterminals(tsub));
		return pts;
	}
}
